package gui;

/**
 * <b>Project ChatSystemG6 INSA 4INFOA1 - 2013/2014</b>
 * <P>
 * <i>Package gui </i> <br>
 * Class DiscussionTab is launch when the user open a new discussion with a remote user<br>
 * 
 * @author Christelle SIAGO HAPPI
 */
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.imageio.ImageIO;
import javax.swing.Box;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.text.BadLocationException;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;
import exceptions.FileException;

import model.data.Audio;
import model.data.FileDescription;

public class DiscussionTab extends JPanel implements ActionListener {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private String username;
	private JTabbedPane multichatArea;
	private JButton disconnectButton;
	private JTextArea conversationText;
	private JScrollPane conversationScroll;
	private JButton sendMsgButton;
	private JTextArea tsendMessage;
	private JTextArea tReceiveMessage;
	private JLabel sendMessageLabel;
	private JLabel receivedMessageLabel;
	private JButton closeTab;
	private JButton sendFileButton;
	private ChatGUI gui;
	private String remoteUser;
	private String localUser;
	private JLabel barreEtat;
	private JTextField notificationArea;
	private JScrollPane receiveArea;
	private ImagePanel panel;

	// Composants de style
	private Font font;
	private StyledDocument doc;
	private Style local;
	private Style remote;
	private JTextPane areaConversation;
	private TabBackgroundImage panelfond;
	private Font comp;
	private int pos;
	private boolean notified;
	private Style composing;

	public DiscussionTab(String username, JTabbedPane multichatArea)
			throws IOException {
		this.username = username;
		this.multichatArea = multichatArea;
		initComponents();

	}

	/**
	 * 
	 * @param gui
	 */
	public DiscussionTab(ChatGUI gui) {
		this.gui = gui;
	}

	/**
	 * 
	 * @param myGui
	 */
	public void setGui(ChatGUI myGui) {
		this.gui = myGui;
	}

	/**
	 * 
	 * @param b
	 */
	public void enableSendButton(boolean b) {
		this.sendMsgButton.setEnabled(b);
	}

	/**
	 * iniy the components
	 * 
	 * @throws IOException
	 */
	private void initComponents() throws IOException {

		pos = 0;
		notified = false;
		font = new Font("Tahoma", Font.ITALIC, 13);
		comp = new Font("Tahoma", Font.ITALIC, 10);

		panelfond = new TabBackgroundImage(ImageIO.read(getClass().getResource(
				"/ressources/background.jpg")));
		panelfond.repaint();
		panelfond.setOpaque(false);

		disconnectButton = new JButton("disconnect");
		disconnectButton.addActionListener(this);
		sendMsgButton = new JButton("send message");
		sendMsgButton.addActionListener(this);
		// sendMsgButton.setFont(new Font("Tahoma", 2, 11));
		sendMsgButton.setForeground(new Color(0, 153, 255));
		// sendMsgButton.setEnabled(false);

		tsendMessage = new JTextArea();
		tReceiveMessage = new JTextArea();

		tsendMessage.addKeyListener(new KeyAdapter() {
			public void keyPressed(KeyEvent evt) {
				areaMsgKeyPressed(evt);
			}

			public void keyReleased(KeyEvent evt) {
				areaMsgKeyReleased(evt);
			}

		});

		notificationArea = new JTextField();
		notificationArea.setFont(new Font("Tahoma", 2, 11));
		notificationArea.setForeground(new Color(0, 153, 204));
		notificationArea.setBackground(Color.CYAN);

		sendMessageLabel = new JLabel("Type a message");
		receivedMessageLabel = new JLabel("Received message ");

		// Icon ico = new ImageIcon("/ressources/ssend.ico");
		sendFileButton = new JButton("send a File" /* , ico */);
		sendFileButton.addActionListener(this);
		sendFileButton.setFont(new Font("Tahoma", 2, 11));
		sendFileButton.setForeground(new Color(0, 153, 255));

		barreEtat = new JLabel();
		notificationArea.setText(this.remoteUser + " vient de se connecter");

		areaConversation = new JTextPane();
		areaConversation.setBackground(Color.CYAN);
		areaConversation.setSize(300, 300);
		areaConversation.setOpaque(false);
		areaConversation.setEditable(false);
	

		Box b1 = Box.createHorizontalBox();
		b1.add(sendMessageLabel);
		b1.add(tsendMessage);
		// b1.add(sendMsgButton);
		// b1.add(sendFileButton);

		Box b2 = Box.createVerticalBox();
		// b2.add(closeTab);
		b2.add(sendMsgButton);
		b2.add(Box.createGlue());
		b2.add(sendFileButton);

		Box b3 = Box.createHorizontalBox();
		b3.add(b1);
		b3.add((Box.createHorizontalStrut(5)));
		b3.add(b2);

		Box b4 = Box.createVerticalBox();
		b4.add(b3);
		b4.add(Box.createGlue());
		b4.add(notificationArea);

		/*
		 * tReceiveMessage = new JTextArea();
		 * this.tReceiveMessage.setBackground(Color.CYAN);
		 * this.tReceiveMessage.setFont(new Font("Tahoma", 2, 11));
		 * tReceiveMessage.setEditable(false);
		 */

		receiveArea = new JScrollPane(areaConversation);
		receiveArea
				.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
		receiveArea.setPreferredSize(new Dimension(350, 250));

		this.setLayout(new BorderLayout());
		this.add(new JSplitPane(JSplitPane.VERTICAL_SPLIT, receiveArea, b4),
				BorderLayout.CENTER);
		this.add(
				new JSplitPane(JSplitPane.VERTICAL_SPLIT, b4, notificationArea),
				BorderLayout.SOUTH);

		setJTextPaneFont();
		
		this.setVisible(true);

	}

	/**
	 * 
	 * @return
	 */
	public String getLocalUser() {
		this.localUser = gui.getLocalUser();
		return localUser;
	}

	/**
	 * 
	 * @param localUser
	 */
	public void setLocalUser(String localUser) {
		this.localUser = localUser;
	}

	/**
	 * get the remote user
	 * 
	 * @return
	 */
	public String getRemoteUser() {
		this.remoteUser = gui.getRemoteUser();
		return remoteUser;
	}

	/**
	 * 
	 * @param remoteUser
	 */
	public void setRemoteUser(String remoteUser) {
		this.remoteUser = remoteUser;
	}

	/**
	 * called when a message is received
	 * 
	 * @param text
	 * @throws BadLocationException
	 */
	public void receivedMessage(String text) throws BadLocationException {
		text = remoteUser + " >> " + text + "\n\n";
		this.insertRemoteString(text);
	}

	/**
	 * action performed when the user send a message
	 */
	@Override
	public void actionPerformed(ActionEvent arg0) {
		if (arg0.getSource().equals(sendMsgButton)) {

			if (!tsendMessage.getText().equals("")) {
				String message = "Me >> " + tsendMessage.getText() +"\n";
				this.gui.sendMessage(localUser, remoteUser,
						tsendMessage.getText());

				try {
					insertLocalString(message);

					// this.areaConversation.ad
					tsendMessage.setText("");
					barreEtat.setText(this.remoteUser + " is online");
				} catch (BadLocationException e) {
					JOptionPane.showMessageDialog(this,
							"Une erreur est survenue", "Erreur",
							JOptionPane.ERROR_MESSAGE);
					e.printStackTrace();
				}

			}

		}

		if (arg0.getSource().equals(sendFileButton)) {
			sendFile();
		}

	}

	/**
	 * send a file
	 */
	private void sendFile() {
		if (gui.selectUser(true)) { // a user has been selected

			// creation of the file description
			JFileChooser chooser = new JFileChooser();
			chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
			FileNameExtensionFilter filter = new FileNameExtensionFilter(
					"File TXT", "txt");
			chooser.setFileFilter(filter);

			int returnVal = chooser.showOpenDialog(this);
			if (returnVal == JFileChooser.APPROVE_OPTION) {

				try {

					String filename = chooser.getSelectedFile().getPath();

					FileDescription file = new FileDescription(filename);
					String message = "File Transfert request . . .\n";
					setNotification(message);
					gui.sendFileRequest(file, remoteUser);

				} catch (FileException ex) {
					Logger.getLogger(ChatGUI.class.getName()).log(Level.SEVERE,
							"Error", ex);
				}
			}
		} else {
			Audio audio = new Audio("/ressources/select.wav");
			JOptionPane.showMessageDialog(this,
					"Selectionnez un contact dans la liste", "Aucun contact",
					JOptionPane.ERROR_MESSAGE);

		}
	}

	/**
	 * set a new notification
	 * 
	 * @param msg
	 */

	public void setNotification(String msg) {
		this.notificationArea.setText(msg);

	}

	/**
	 * send a message with the entry key
	 * 
	 * @param evt
	 */
	private void areaMsgKeyReleased(KeyEvent evt) {
		if (remoteUser != null && evt.getKeyCode() != KeyEvent.VK_ENTER) {
			try {
				this.gui.remoteIsWriting(remoteUser, false);
				//this.insertComposing(remoteUser);
			} catch (Exception ex) {
				Logger.getLogger(ChatGUI.class.getName()).log(Level.SEVERE,
						null, ex);
			}
		} else if (remoteUser != null && evt.getKeyCode() == KeyEvent.VK_ENTER) {
			try {
			
				String message = "Moi >> " + tsendMessage.getText() +"\n";
				this.insertLocalString(message);
				this.gui.sendMessage(localUser, remoteUser,
						tsendMessage.getText());
				tsendMessage.setText("");
			} catch (Exception ex) {
				Logger.getLogger(ChatGUI.class.getName()).log(Level.SEVERE,
						null, ex);
				JOptionPane.showMessageDialog(this, "Error detected", "Error",
						JOptionPane.ERROR_MESSAGE);
			}
		}

	}

	/**
	 * allow to send a message by pressing the entry key
	 * 
	 * @param evt
	 */
	private void areaMsgKeyPressed(KeyEvent evt) {
		if (this.remoteUser != null && evt.getKeyCode() != KeyEvent.VK_ENTER) {
			try {
				this.gui.remoteIsWriting(remoteUser, true);
			} catch (Exception ex) {
				Logger.getLogger(ChatGUI.class.getName()).log(Level.SEVERE,
						null, ex);
			}

		}
	}

	/**
	 Sets the font and style to use for the conversation area
	 */
	private void setJTextPaneFont() {

		Style defaut = areaConversation.getStyle("defaut");
		this.local = areaConversation.addStyle("local", defaut);
		this.remote = areaConversation.addStyle("remote", local);
		this.composing = areaConversation.addStyle("composing", local);

		StyleConstants.setFontFamily(local, font.getFamily());
		StyleConstants.setFontFamily(remote, font.getFamily());
		StyleConstants.setFontFamily(composing, comp.getFamily());

		StyleConstants.setFontSize(local, font.getSize());
		StyleConstants.setFontSize(remote, font.getSize());
		StyleConstants.setFontSize(composing, comp.getSize());

		StyleConstants.setItalic(local, (font.getStyle() & Font.ITALIC) != 0);
		StyleConstants.setItalic(remote, (font.getStyle() & Font.ITALIC) != 0);
		StyleConstants.setItalic(composing,
				(comp.getStyle() & Font.ITALIC) != 0);

		// Set the font color
		StyleConstants.setForeground(local, Color.BLACK);
		StyleConstants.setForeground(remote, Color.BLUE);
		StyleConstants.setForeground(composing, Color.GRAY);

		// Retrieve the pane's document object
		doc = areaConversation.getStyledDocument();

		doc.setCharacterAttributes(0, doc.getLength() + 1, local, false);
		doc.setCharacterAttributes(0, doc.getLength() + 1, remote, false);
		doc.setCharacterAttributes(0, doc.getLength() + 1, composing, false);
	}

	/**
	 * Edits the text message written by the local user
	 * 
	 * @param message
	 *            message to send
	 * @throws BadLocationException
	 */
	public void insertLocalString(String message) throws BadLocationException {
		doc.insertString(pos, message, local);
		panelfond.repaint();
		pos += message.length();
	}

	/**
	 * Edits the text message written by the remote user
	 * 
	 * @param message
	 *            message received
	 * @throws BadLocationException
	 */
	public void insertRemoteString(String message) throws BadLocationException {
		doc.insertString(pos, message, remote);
		panelfond.repaint();
		pos += message.length();
	}

	/**
	 *edits  notification Writing received from a remote user
	 * 
	 * @param remoteLogin
	 *           
	 * @throws BadLocationException
	 */
	public void insertComposing(String remoteLogin) throws BadLocationException {
		String notif = "( " + remoteLogin
				+ " is writing a new message )";
		this.deleteComposing(remoteLogin);
		doc.insertString(pos, notif, composing);
		notified = true;
		panelfond.repaint();
	}

	/**
	 *Removes the notification Writing received from a remote user
	 * 
	 * @param remoteLogin
	 *            
	 * @throws BadLocationException
	 */
	public void deleteComposing(String remoteLogin) throws BadLocationException {
		String notif = "( " + remoteLogin
				+ " is writing a new message )";
		if (notified)
			doc.remove(pos, notif.length());
		notified = false;
		panelfond.repaint();
	}
	
	
}
